package com.uuah.server.config.spring.parsers.delegate;

import java.util.Map;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

import com.uuah.server.config.spring.parsers.AbstractUuahBeanDefinitionParser;
import com.uuah.server.config.spring.parsers.IUuahDefinitionParser;
import com.uuah.server.config.spring.parsers.IUuahDefinitionParserConfiguration;
import com.uuah.server.config.spring.parsers.PostProcessor;
import com.uuah.server.config.spring.parsers.PreProcessor;
import com.uuah.server.config.spring.parsers.assembly.configuration.IPropertyConfiguration;
import com.uuah.server.config.spring.parsers.assembly.configuration.IValueMap;
import com.uuah.server.config.spring.parsers.assembly.configuration.SimplePropertyConfiguration;
import com.uuah.server.config.spring.parsers.collection.IDynamicAttributeDefinitionParser;
import com.uuah.server.config.spring.parsers.generic.AutoIdUtils;
import com.uuah.server.util.spring.SpringXMLUtils;

/**
 * This is a very hurried demonstration. It needs improving!
 */
public class AllAttributeChildDefinitionParser extends
		AbstractBeanDefinitionParser implements IUuahDefinitionParser {

	private IDynamicAttributeDefinitionParser delegate;
	private IPropertyConfiguration configuration = new SimplePropertyConfiguration();

	public AllAttributeChildDefinitionParser(
			IDynamicAttributeDefinitionParser delegate) {
		addIgnored(AbstractUuahBeanDefinitionParser.ATTRIBUTE_ID);
		addIgnored(AbstractUuahBeanDefinitionParser.ATTRIBUTE_NAME);
		this.delegate = delegate;
	}

	protected AbstractBeanDefinition parseInternal(Element element,
			ParserContext parserContext) {
		NamedNodeMap attributes = element.getAttributes();
		for (int i = 0; i < attributes.getLength(); ++i) {
			String name = SpringXMLUtils.attributeName((Attr) attributes
					.item(i));
			if (!isIgnored(name)) {
				delegate.setAttributeName(name);
				delegate.uuahParse(element, parserContext);
			}
		}
		return null;
	}

	public AbstractBeanDefinition uuahParse(Element element,
			ParserContext parserContext) {
		return parseInternal(element, parserContext);
	}

	public IUuahDefinitionParserConfiguration registerPreProcessor(
			PreProcessor preProcessor) {
		delegate.registerPreProcessor(preProcessor);
		return this;
	}

	public IUuahDefinitionParserConfiguration registerPostProcessor(
			PostProcessor postProcessor) {
		delegate.registerPostProcessor(postProcessor);
		return this;
	}

	public IUuahDefinitionParserConfiguration addReference(String propertyName) {
		configuration.addReference(propertyName);
		return this;
	}

	public IUuahDefinitionParserConfiguration addMapping(String propertyName,
			Map mappings) {
		configuration.addMapping(propertyName, mappings);
		return this;
	}

	public IUuahDefinitionParserConfiguration addMapping(String propertyName,
			String mappings) {
		configuration.addMapping(propertyName, mappings);
		return this;
	}

	public IUuahDefinitionParserConfiguration addMapping(String propertyName,
			IValueMap mappings) {
		configuration.addMapping(propertyName, mappings);
		return this;
	}

	public IUuahDefinitionParserConfiguration addAlias(String alias,
			String propertyName) {
		configuration.addAlias(alias, propertyName);
		return this;
	}

	public IUuahDefinitionParserConfiguration addCollection(String propertyName) {
		configuration.addCollection(propertyName);
		return this;
	}

	public IUuahDefinitionParserConfiguration addIgnored(String propertyName) {
		configuration.addIgnored(propertyName);
		return this;
	}

	public IUuahDefinitionParserConfiguration removeIgnored(String propertyName) {
		configuration.removeIgnored(propertyName);
		return this;
	}

	public IUuahDefinitionParserConfiguration setIgnoredDefault(boolean ignoreAll) {
		configuration.setIgnoredDefault(ignoreAll);
		return this;
	}

	public String getAttributeMapping(String alias) {
		return configuration.getAttributeMapping(alias);
	}

	public boolean isCollection(String propertyName) {
		return configuration.isCollection(propertyName);
	}

	public boolean isIgnored(String propertyName) {
		return configuration.isIgnored(propertyName);
	}

	public boolean isBeanReference(String attributeName) {
		return configuration.isReference(attributeName);
	}

	public String translateName(String oldName) {
		return configuration.translateName(oldName);
	}

	public Object translateValue(String name, String value) {
		return configuration.translateValue(name, value);
	}

	public String getBeanName(Element element) {
		return AutoIdUtils.getUniqueName(element, "all-attribute");
	}

	public IUuahDefinitionParserConfiguration addBeanFlag(String flag) {
		delegate.addBeanFlag(flag);
		return this;
	}

}
